#include <sys/types.h>
#include <pthread.h>
#include "wrap.h"

typedef struct client_info{
    int client_fd;
    struct sockaddr_in client_addr;
} c_info;

/**
 * 线程需要完成的任务
 * @param arg
 * @return
 */
void * client_fun(void * arg){
    c_info * info = (c_info *) arg;
    char ip[16] = "";
    printf("客户端：%s:%d 链接了服务器。。。。。。！\n", inet_ntop(AF_INET,&(info->client_addr.sin_addr.s_addr),ip,16), ntohs(info->client_addr.sin_port));
    while (1){
        char buff[1024] = "";
        int count = 0;
        count = read(info->client_fd,buff,sizeof(buff));
        if(count < 0){
            perror("read");
            break;
        }
        else if(count == 0){
            printf("客户端关闭！\n");
            break;
        }
        else{
            printf("%s:%d=>>>%s",ip,ntohs(info->client_addr.sin_port),buff);
            write(info->client_fd,buff,count);
        }
    }
    printf("客户端：%s:%d 和服务器断开了链接。。。。。。！\n", inet_ntop(AF_INET,&(info->client_addr.sin_addr.s_addr),ip,16), ntohs(info->client_addr.sin_port));
    close(info->client_fd);
    free(info);
    return NULL;
}

/**
 * 多线程实现 服务器
 * gcc main.c wrap.c -lpthread
 * @return
 */
int main(int argc,char * argv[]) {
    //if(argc < 2){
    //    printf("argc < 2 need param like ./a.out 8080\n");
    //}
    //设置线程分离，线程在完成使命后自动的去释放资源
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

    // 创建套接字
    int socket_fd = tcp4bind(8080,NULL);
    // 监听
    Listen(socket_fd,128);
    struct sockaddr_in client_addr;
    socklen_t len = sizeof(client_addr);
    // 为了不让数据覆盖，我们需要在堆中创建一个空间用来存放数据，在线程中释放
    c_info * cInfo;
    while(1){
        //提取
        int client_fd = Accept(socket_fd,(struct sockaddr *) &client_addr,&len);

        cInfo = malloc(sizeof(c_info));
        cInfo->client_fd = client_fd;
        cInfo->client_addr = client_addr;
        //线程创建
        pthread_t tid;
        pthread_create(&tid,&attr,client_fun,cInfo);
    }

    return 1;
}

